package upbeat;

import upbeat.types.Cue;
import java.util.LinkedList;
import upbeat.jmusiclib.JMusicWrapper;
import upbeat.jmusiclib.JMusicWrapperInterface;

/**
 * This is the interface to the Manager classes.  At the start of the program, the
 * {@link UpbeatApplication} is going to create an object that implements the 
 * Manager interface.<br/>
 * 
 * The Manager will be the central "hub" of the runtime environment and, as such,
 * must interact with all of the different components in the runtime environment.
 * Described below are the classes that a Manager interacts with and what the
 * purpose of said interaction is.  Note: The Manager interface only provides
 * methods for other classes to interact with the Manager with.  All methods
 * that allow a Manager to affect outgoing changes are left up to the implementation.<br/>
 * 
 * <ul>
 * <li><b>{@link UpbeatApplication}:</b> The Manager is created by the UpbeatApplication.
 * Furthermore, the UpbeatApplication is going to give the Manager pointers to
 * the {@link Conductor} and {@link Musician}s that the Manager needs to interact
 * with.  Finally, the UpbeatApplication gives the Manager the name of the input
 * (either a file or some source of real-time data, depending on the implementation
 * of the Manager).  From a high level point of view, the Manager is responsible for
 * reading the input and providing it to the {@link Conductor} in a timely manner.
 * However, it is likely that this particular functionality will be factored into
 * its own class.  Since the type of input is implementation-specific, it is not
 * dealt with here.</li>
 * 
 * <li><b>{@link Conductor}:</b> As stated above, the Manager is responsible for providing
 * timely input to the Conductor.  However, the Manager is also responsible for
 * handling {@link Cue}s given to it by the Conductor.  Therefore, this interface
 * provides methods for the Conductor to add Cues.  The Manager is then responsible
 * for making sure that these Cues are dispatched to the {@Musician}s in a timely
 * fashion.</li>
 * 
 * <li><b>{@link Musician}:</b> The Manager is responsible for providing {@link Cue}s to
 * the Musicians in a timely fashion.  Tentatively, in the offline case the
 * Manager will also have to stitch together the individual tracks created
 * by the Musicians.  However, all of this functionality is going to be in
 * the Musician interface, so there will be very little in the Manager interface
 * having to do with Musicians.</li>
 * </ul>
 * 
 * @author Matt
 *
 */
public abstract class Manager {
	protected TempoOptions mOptions;
	protected ConductorInterface mConductor;
	protected LinkedList<MusicianInterface> mMusicians;
	protected JMusicWrapperInterface jMusicWrapper;
	
	
	protected Manager(){
		mMusicians = new LinkedList<MusicianInterface>();
	}
	
	/**
	 * This method is used by the {@link UpbeatApplication} to set the input source
	 * @param source	the source of the input.  Could be a file name, RSS feed, etc....
	 * @return	returns whether or not the input source was successfully accessed.
	 */
	public abstract boolean SetInputSource( String source );
	
	public void SetJMusicWrapper(JMusicWrapperInterface jMusicWrapper) {
		this.jMusicWrapper = jMusicWrapper;
	}
	
	/**
	 * This method is used by the {@link UpbeatApplication} to set the {@link TempoOptions}
	 * of the output music.
	 * @param options	the tempo options to be used when generating music.
	 */
	public void SetTempoOptions( TempoOptions options ) {
		mOptions = options;
		// Let the MIDI code know the tempo of the song
		jMusicWrapper.setTempo(options.TEMPO);
	}
	
	/**
	 * This method gets the tempo options.
	 * @return	the tempo options
	 */
	public TempoOptions GetTempoOptions() {
		return mOptions;
	}
	
	/**
	 * This method is used by the {@link UpbeatApplication} to set the {@link Conductor}.
	 * Note that there may only be one Conductor per Manager.
	 * @param conductor		A reference to the {@link Conductor}.  Must be already instantiated!
	 */
	public void SetConductor( ConductorInterface conductor ) {
		mConductor = conductor;
	}
	
	/**
	 * Adds a reference to a {@link Musician} to the Manager's stable of Musicians.  This is
	 * used by the {@link UpbeatApplication} after it has instantiated each of the Musicians<br/><br/>
	 * 
	 * Note that when we add a Musician, we will need to give it an appropriate {@link Track} class.  Which
	 * MusicMaker we give it will be dependent on whether we're running in real time or offline.  Therefore, we
	 * will leave the implementation of this method to the Offline and RealTime subclasses of Manager.
	 * 
	 * @param musician	A reference to the {@link Musician}.  Must be already instantiated!
	 */
	public abstract void AddMusician( MusicianInterface musician );
	
	/**
	 * Once the {@link Conductor}, {@link Musician}s, and input have been set, call this to
	 * start making music!
	 * @throws Exception 
	 */
	public abstract void MakeSomeMusic() throws Exception;
	
	/**
	 * Used by the {@link Conductor} to add cues to the score.
	 * @param cueToAdd	Reference to the cue to add.  Note that in the implementations, you
	 * should always make a copy of this!!!!!!
	 */
	public abstract void AddCueToScore( Cue cueToAdd );
}




